#include "IngenicEncoder.h"
#include <iostream>
#include <random>
#include <algorithm>

IngenicEncoder::IngenicEncoder()
    : m_width(0)
    , m_height(0)
    , m_fps(0)
    , m_bitrate(0)
    , m_initialized(false)
    , m_timestamp(0)
    , m_frameCount(0)
    , m_spsPpsGenerated(false)
    , m_keyFrameInterval(30) // 每30帧一个I帧
    , m_gopSize(30)
{
    // 初始化编码器参数
    m_encoderParams.profile = 77; // Main Profile
    m_encoderParams.level = 40;   // Level 4.0
    m_encoderParams.qp = 23;      // 中等质量
    m_encoderParams.maxQp = 51;   // 最大QP
    m_encoderParams.minQp = 10;   // 最小QP
}

IngenicEncoder::~IngenicEncoder() {
    Shutdown();
}

bool IngenicEncoder::Initialize(int width, int height, int fps, int bitrate) {
    std::lock_guard<std::mutex> lock(m_encoderMutex);
    
    if (m_initialized) {
        return true;
    }

    m_width = width;
    m_height = height;
    m_fps = fps;
    m_bitrate = bitrate;
    
    // 计算GOP大小和I帧间隔
    m_gopSize = std::max(1, fps * 2); // 2秒一个GOP
    m_keyFrameInterval = m_gopSize;
    
    // 初始化COM（如果需要）
    if (!EnsureCOM()) {
        std::cerr << "IngenicEncoder: COM initialization failed" << std::endl;
        return false;
    }
    
    // 初始化模拟编码器
    if (!InitializeSimulatedEncoder()) {
        std::cerr << "IngenicEncoder: Failed to initialize simulated encoder" << std::endl;
        return false;
    }
    
    m_initialized = true;
    return true;
}

bool IngenicEncoder::InitializeSimulatedEncoder() {
    // 生成SPS和PPS
    GenerateSPSPPS();
    m_spsPpsGenerated = true;
    
    std::cout << "IngenicEncoder: Simulated encoder initialized" << std::endl;
    std::cout << "  Resolution: " << m_width << "x" << m_height << std::endl;
    std::cout << "  Framerate: " << m_fps << " fps" << std::endl;
    std::cout << "  Bitrate: " << m_bitrate << " kbps" << std::endl;
    std::cout << "  GOP Size: " << m_gopSize << std::endl;
    
    return true;
}

void IngenicEncoder::GenerateSPSPPS() {
    // 生成SPS (Sequence Parameter Set)
    m_sps.clear();
    m_sps.push_back(0x00); m_sps.push_back(0x00); m_sps.push_back(0x00); m_sps.push_back(0x01); // Start code
    m_sps.push_back(0x67); // NAL unit type: SPS
    m_sps.push_back(0x42); // profile_idc: Main Profile
    m_sps.push_back(0x00); // constraint_set0_flag, constraint_set1_flag, etc.
    m_sps.push_back(0x1E); // level_idc: Level 3.0
    m_sps.push_back(0xE1); // seq_parameter_set_id: 0, log2_max_frame_num_minus4: 4
    m_sps.push_back(0x00); // pic_order_cnt_type: 0
    m_sps.push_back(0x00); // log2_max_pic_order_cnt_lsb_minus4: 0
    m_sps.push_back(0x00); // num_ref_frames: 0
    m_sps.push_back(0x00); // gaps_in_frame_num_value_allowed_flag: 0
    m_sps.push_back(0x00); // pic_width_in_mbs_minus1: (width/16-1) & 0xFF
    m_sps.push_back(0x00); // pic_height_in_map_units_minus1: (height/16-1) & 0xFF
    m_sps.push_back(0x00); // frame_mbs_only_flag: 1, direct_8x8_inference_flag: 0
    m_sps.push_back(0x00); // frame_cropping_flag: 0
    m_sps.push_back(0x00); // vui_parameters_present_flag: 0
    m_sps.push_back(0x80); // rbsp_stop_one_bit: 1, trailing bits
    
    // 生成PPS (Picture Parameter Set)
    m_pps.clear();
    m_pps.push_back(0x00); m_pps.push_back(0x00); m_pps.push_back(0x00); m_pps.push_back(0x01); // Start code
    m_pps.push_back(0x68); // NAL unit type: PPS
    m_pps.push_back(0x00); // pic_parameter_set_id: 0
    m_pps.push_back(0x00); // seq_parameter_set_id: 0
    m_pps.push_back(0x00); // entropy_coding_mode_flag: 0, pic_order_present_flag: 0
    m_pps.push_back(0x00); // num_slice_groups_minus1: 0
    m_pps.push_back(0x00); // num_ref_idx_l0_active_minus1: 0
    m_pps.push_back(0x00); // num_ref_idx_l1_active_minus1: 0
    m_pps.push_back(0x00); // weighted_pred_flag: 0, weighted_bipred_idc: 0
    m_pps.push_back(0x00); // pic_init_qp_minus26: 0
    m_pps.push_back(0x00); // pic_init_qs_minus26: 0
    m_pps.push_back(0x00); // chroma_qp_index_offset: 0
    m_pps.push_back(0x00); // deblocking_filter_control_present_flag: 0
    m_pps.push_back(0x00); // constrained_intra_pred_flag: 0
    m_pps.push_back(0x00); // redundant_pic_cnt_present_flag: 0
    m_pps.push_back(0x80); // rbsp_stop_one_bit: 1, trailing bits
}

bool IngenicEncoder::EncodeFrame(const unsigned char* nv12Data, std::vector<unsigned char>& outputData) {
    if (!m_initialized) return false;
    
    std::lock_guard<std::mutex> lock(m_encoderMutex);
    
    // 使用模拟编码器
    return EncodeFrameSimulated(nv12Data, outputData);
}

bool IngenicEncoder::EncodeFrameSimulated(const unsigned char* nv12Data, std::vector<unsigned char>& outputData) {
    outputData.clear();
    
    int currentFrame = m_frameCount.fetch_add(1);
    
    // 如果是关键帧间隔，生成I帧
    if (currentFrame % m_keyFrameInterval == 0) {
        GenerateIDRFrame();
        outputData.insert(outputData.end(), m_sps.begin(), m_sps.end());
        outputData.insert(outputData.end(), m_pps.begin(), m_pps.end());
    } else {
        GeneratePFrame();
    }
    
    // 模拟编码延迟
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
    
    return true;
}

void IngenicEncoder::GenerateIDRFrame() {
    // 生成IDR帧的模拟数据
    // 这里只是示例，实际应该调用君正编码器
    std::cout << "Generating IDR frame" << std::endl;
}

void IngenicEncoder::GeneratePFrame() {
    // 生成P帧的模拟数据
    // 这里只是示例，实际应该调用君正编码器
    std::cout << "Generating P frame" << std::endl;
}

bool IngenicEncoder::GetCodecConfig(std::vector<unsigned char>& outConfigBlob) {
    if (!m_initialized || !m_spsPpsGenerated) {
        return false;
    }
    
    outConfigBlob.clear();
    
    // 生成AVCDecoderConfigurationRecord
    outConfigBlob.push_back(0x01); // configurationVersion
    outConfigBlob.push_back(0x42); // AVCProfileIndication (Main Profile)
    outConfigBlob.push_back(0x00); // profile_compatibility
    outConfigBlob.push_back(0x1E); // AVCLevelIndication (Level 3.0)
    outConfigBlob.push_back(0xFF); // lengthSizeMinusOne (3, so length is 4 bytes)
    outConfigBlob.push_back(0xE1); // numOfSequenceParameterSets (1) + reserved bits
    
    // SPS长度和内容
    uint16_t spsLen = static_cast<uint16_t>(m_sps.size() - 4); // 减去start code
    outConfigBlob.push_back((spsLen >> 8) & 0xFF);
    outConfigBlob.push_back(spsLen & 0xFF);
    outConfigBlob.insert(outConfigBlob.end(), m_sps.begin() + 4, m_sps.end());
    
    // PPS数量
    outConfigBlob.push_back(0x01); // numOfPictureParameterSets
    
    // PPS长度和内容
    uint16_t ppsLen = static_cast<uint16_t>(m_pps.size() - 4); // 减去start code
    outConfigBlob.push_back((ppsLen >> 8) & 0xFF);
    outConfigBlob.push_back(ppsLen & 0xFF);
    outConfigBlob.insert(outConfigBlob.end(), m_pps.begin() + 4, m_pps.end());
    
    return true;
}

void IngenicEncoder::Shutdown() {
    std::lock_guard<std::mutex> lock(m_encoderMutex);
    
    if (m_initialized) {
        m_initialized = false;
        m_spsPpsGenerated = false;
        m_sps.clear();
        m_pps.clear();
        
        std::cout << "IngenicEncoder: Shutdown complete" << std::endl;
    }
}

bool IngenicEncoder::EnsureCOM() {
    // Windows COM初始化
    HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
    return (hr == S_OK || hr == S_FALSE || hr == RPC_E_CHANGED_MODE);
}

void IngenicEncoder::SetBitrate(int bitrate) {
    std::lock_guard<std::mutex> lock(m_encoderMutex);
    m_bitrate = bitrate;
}

void IngenicEncoder::SetFramerate(int fps) {
    std::lock_guard<std::mutex> lock(m_encoderMutex);
    m_fps = fps;
    m_gopSize = std::max(1, fps * 2);
    m_keyFrameInterval = m_gopSize;
}

void IngenicEncoder::SetResolution(int width, int height) {
    std::lock_guard<std::mutex> lock(m_encoderMutex);
    m_width = width;
    m_height = height;
}
